﻿using System;
using System.Globalization;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.IO;
using System.Windows.Forms;
namespace System
{
	public partial class Poly3G
	{
		public V3G[] Points;
		public bool CW;
		public Poly3G()
		{
			Points = null;
		}
		public Poly3G(V3G[] Pts)
		{
			Points= new V3G[Pts.Length];
			Array.Copy(Pts, Points, Pts.Length);
			GetDir();
			MinMax();
		}
		public void GetDir()
		{
			double a = 0;
			for (int i = 0; i < Points.Length; i++)
			{
				int i2 = (i + 1) % Points.Length;
				int i3 = (i + 2) % Points.Length;
				V3D p1 = new V3D(Points[i].Longitude, Points[i].Latitude, 0);
				V3D p2 = new V3D(Points[i2].Longitude, Points[i2].Latitude, 0);
				V3D p3 = new V3D(Points[i3].Longitude, Points[i3].Latitude, 0);
				V3D A = (V3D)p2 - (V3D)p1;
				V3D B = (V3D)p3 - (V3D)p2;
				double d = V3D.AbsAngleD(A, B, V3D.Blue);
				if (d == 180)
				{
				}
				a += d;
			}
			if (a < 361)
				CW = a < 0;
			else
			{
				CW = false;
			}
			if (a < 0)
			{
				CW = !CW;
			}
			//Console.WriteLine(a);
		}

		public void MinMax()
		{
			for (int i = 0; i < Points.Length; i++)
			{
				Min.Longitude = i == 0 ? Points[0].Longitude : Math.Min(Min.Longitude, Points[i].Longitude);
				Min.Latitude = i == 0 ? Points[0].Latitude : Math.Min(Min.Latitude, Points[i].Latitude);
				Max.Longitude = i == 0 ? Points[0].Longitude : Math.Max(Max.Longitude, Points[i].Longitude);
				Max.Latitude = i == 0 ? Points[0].Latitude : Math.Max(Max.Latitude, Points[i].Latitude);
				Min.Valid = Max.Valid = true;
			}
		}
		V3G Min;
		V3G Max;
		public bool InPolyQuick(V3G P)
		{
			if (!Min.Valid || !Max.Valid || !P.Valid)
				return false;
			if (P.Longitude >= Min.Longitude && P.Longitude <= Max.Longitude && P.Latitude >= Min.Latitude && P.Latitude <= Max.Latitude)
				return true;
			return false;
		}
		public bool PointInPolygon(V3G P)
		{
			if (!InPolyQuick(P))
				return false;
			int N = 0;
			for (int i = 0; i < Points.Length; i++)
			{
				V3G M = new Line3G(new V3G(P.Longitude, 89.99, P._Height), P, false) * new Line3G(Points[i], Points[(i + 1) % Points.Length], false);
				if (M.Valid)
					N++;
			}
			bool Test1 = N % 2 == 1;
			N = 0;
			for (int i = 0; i < Points.Length; i++)
			{
				V3G M = new Line3G(new V3G(P.Longitude + Math.Sqrt(2), -89.99, P._Height), P, false) * new Line3G(Points[i], Points[(i + 1) % Points.Length], false);
				if (M.Valid)
					N++;
			}
			bool Test2 = N % 2 == 1;
			return Test1 && Test2;
		}
		public bool PointInPolygon2(V3G P)
		{
			if (!InPolyQuick(P))
				return false;
			int N = 0;
			for (int i = 0; i < Points.Length; i++)
			{
				int i2=(i + 1) % Points.Length;
				if (P.Longitude < Points[i].Longitude && P.Longitude < Points[i2].Longitude)
					continue;
				if (P.Longitude > Points[i].Longitude && P.Longitude > Points[i2].Longitude)
					continue;
				if (P.Longitude == Points[i].Longitude && P.Longitude == Points[i2].Longitude)
				{
					Console.WriteLine("Vertical line found!!");
					continue;
				}
				V3G M = new Line3G(new V3G(P.Longitude, 89.99, P._Height), P, false) * new Line3G(Points[i], Points[i2], false);
				if (M.Valid)
					N++;
			}
			bool Test1 = N % 2 == 1;
			return Test1 ;
		}
		void Log(String S)
		{
			File.AppendAllText("debug.txt", S + "\r\n");
		}
	}
}